home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / win.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  28.9 KB  |  1,326 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: win.c 1.1 1994/08/09 23:35:26 digulla Exp digulla $
  5.  
  6.     DESCRIPTION
  7.     Everything for windows and GUI
  8.  
  9.     NOTES
  10.  
  11.     BUGS
  12.  
  13.     TODO
  14.  
  15.     EXAMPLES
  16.  
  17.     SEE ALSO
  18.  
  19.     INDEX
  20.  
  21.     HISTORY
  22.     14. Nov 1992    ada created
  23.     $Log: win.c $
  24.  * Revision 1.1  1994/08/09  23:35:26  digulla
  25.  * Initial revision
  26.  *
  27.  
  28. ******************************************************************************/
  29.  
  30. /**************************************
  31.         Includes
  32. **************************************/
  33. #include "defs.h"
  34. #include <graphics/text.h>
  35. #include <intuition/classusr.h>
  36. #include <intuition/imageclass.h>
  37. #include <intuition/classes.h>
  38. #include <intuition/icclass.h>
  39. #define MYDEBUG 1
  40. #include "debug.h"
  41.  
  42.  
  43. /**************************************
  44.         Globale Variable
  45. **************************************/
  46. Prototype void          do_iconify        (void);
  47. Prototype void          iconify        (void);
  48. Prototype void          uniconify        (void);
  49. Prototype void          do_newwindow        (void);
  50. Prototype void          do_openwindow     (void);
  51. Prototype struct Window * TOpenWindow        (struct NewWindow *);
  52. Prototype struct Window * opensharedwindow  (struct NewWindow *);
  53. Prototype void          closesharedwindow (struct Window *);
  54. Prototype int          getyn         (char *, char *, char *, ...);
  55. Prototype void          title         (char *, ...);
  56. Prototype void          window_title        (void);
  57. Prototype void          set_window_params (void);
  58. Prototype void          do_resize        (void);
  59. Prototype char        * geoskip        (char *, int *, int *);
  60. Prototype void          prop_adj        (void);
  61. Prototype struct PropGadget * add_prop        (struct Window *);
  62. Prototype void          free_prop        (struct PropGadget *);
  63. Prototype void          rem_prop        (ED *);
  64. Prototype void          rest_prop        (ED *);
  65. Prototype ULONG       new_top        (void);
  66. Prototype void          GeometryToNW        (char *, struct NewWindow *);
  67. Prototype void          do_title        (void);
  68. Prototype void          do_showlog        (void);
  69. Prototype void          error         (char *, ...);
  70. Prototype void          warn            (char *, ...);
  71. Prototype void          do_setgeometry    (void);
  72. Prototype void          do_toback        (void);
  73. Prototype void          do_tofront        (void);
  74.  
  75.  
  76. /**************************************
  77.       Interne Defines & Strukturen
  78. **************************************/
  79. #define IDCMPFLAGS   (IDCMP_CLOSEWINDOW |\
  80.               IDCMP_NEWSIZE |\
  81.               IDCMP_RAWKEY |\
  82.               IDCMP_MOUSEBUTTONS |\
  83.               IDCMP_ACTIVEWINDOW |\
  84.               IDCMP_MOUSEMOVE |\
  85.               IDCMP_MENUPICK |\
  86.               IDCMP_GADGETUP |\
  87.               IDCMP_GADGETDOWN |\
  88.               IDCMP_REFRESHWINDOW)
  89.  
  90. #define WINDOWFLAGS  (WFLG_ACTIVATE |\
  91.               WFLG_SIZEGADGET |\
  92.               WFLG_DRAGBAR |\
  93.               WFLG_DEPTHGADGET |\
  94.               WFLG_CLOSEGADGET |\
  95.               WFLG_SIMPLE_REFRESH)
  96.  
  97. #define ICONIFYFLAGS (WFLG_DRAGBAR |\
  98.               WFLG_RMBTRAP |\
  99.               WFLG_DEPTHGADGET |\
  100.               WFLG_SIMPLE_REFRESH)
  101.  
  102.  
  103.  
  104. struct NewWindow Nw =
  105. {
  106.    0, 1, 0  , 0  , 0, 0,  /*  width, height filled in by program */
  107.    IDCMPFLAGS, WINDOWFLAGS,
  108.    NULL, NULL, (UBYTE *)"",
  109.    NULL, NULL,
  110.    100, 50, (UWORD)-1, (UWORD)-1,
  111.    WBENCHSCREEN
  112. };
  113.  
  114. #define NUM_GADS    4
  115.  
  116. struct PropGadget
  117. {
  118.     struct Gadget   scroller;
  119.     struct Gadget   up;
  120.     struct Gadget   down;
  121. #ifdef NOT_DEF
  122.     struct Gadget   depth;
  123. #endif
  124.     struct Gadget   iconify;
  125.     struct PropInfo pinfo;        /* PropInfo for scroller */
  126.     struct Image    simage;        /* image for scroller */
  127.     struct Image  * upimage;
  128.     struct Image  * downimage;
  129. #ifdef NOT_DEF
  130.     struct Image  * depthimage;
  131. #endif
  132.     struct Image  * iconifyimage;
  133. };
  134.  
  135.  
  136. const struct PropGadget gadgetdefaults =
  137. {
  138.     {    /* PropGadget */
  139.     NULL,
  140.     0,0, 0,0,
  141.     GFLG_RELRIGHT|GFLG_RELHEIGHT,
  142.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE|GACT_FOLLOWMOUSE,
  143.     GTYP_PROPGADGET,
  144.     NULL, NULL, NULL, NULL, NULL,
  145.     0, NULL
  146.     },
  147.     {    /* Up-Image */
  148.     NULL,
  149.     0,0, 0,0,
  150.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  151.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  152.     GTYP_BOOLGADGET,
  153.     NULL, NULL, NULL, NULL, NULL,
  154.     1, NULL
  155.     },
  156.     {    /* Down-Gadget */
  157.     NULL,
  158.     0,0, 0,0,
  159.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  160.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  161.     GTYP_BOOLGADGET,
  162.     NULL, NULL, NULL, NULL, NULL,
  163.     2, NULL
  164.     },
  165. #ifdef NOT_DEF
  166.     {    /* Depth-Gadget */
  167.     NULL,
  168.     0,0, 0,0,
  169.     GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  170.     GACT_TOPBORDER|GACT_RELVERIFY,
  171.     GTYP_BOOLGADGET,
  172.     NULL, NULL, NULL, NULL, NULL,
  173.     3, NULL
  174.     },
  175. #endif
  176.     {    /* Zoom-Gadget */
  177.     NULL,
  178.     0,0, 0,0,
  179.     GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  180.     GACT_TOPBORDER|GACT_RELVERIFY,
  181.     GTYP_BOOLGADGET,
  182.     NULL, NULL, NULL, NULL, NULL,
  183.     4, NULL
  184.     },
  185.     {    /* PropInfo */
  186.     AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS,
  187.     MAXPOT, MAXPOT,
  188.     MAXBODY, MAXBODY,
  189.     },
  190. };
  191.  
  192.  
  193. /**************************************
  194.         Interne Variable
  195. **************************************/
  196. static UWORD    WIN_MINWIDTH,        /* min. sizes for a window */
  197.         WIN_MINHEIGHT;
  198.  
  199. #define MAX_LOG     10
  200. static char * log_messages[MAX_LOG];
  201. static USHORT numlogs = 0;
  202.  
  203.  
  204. /**************************************
  205.        Interne Prototypes
  206. **************************************/
  207. static void log (char *);
  208. static void StripIntuiMessages (struct MsgPort *,struct Window *);
  209.  
  210.  
  211. void do_iconify (void)
  212. {
  213.     text_sync ();
  214.  
  215.     if (!globalflags.Comlinemode)
  216.     iconify ();
  217. } /* do_iconify */
  218.  
  219.  
  220. /* New iconify() routine by fgk. */
  221.  
  222. void iconify (void)
  223. {
  224.     WIN        * newwin;
  225.     ED           * ep      = Ep;
  226.     WIN        * win     = ep->win;
  227.     struct IntuiText itxt;        /* To find width of prop fonts */
  228.  
  229.     itxt.ITextFont = Ep->win->WScreen->Font;    /* Init */
  230.     itxt.NextText  = NULL;
  231.  
  232.     if (!ep->iconmode)
  233.     {
  234.     ep->config.winx      = win->LeftEdge;
  235.     ep->config.winy      = win->TopEdge;
  236.     ep->config.winwidth  = win->Width;
  237.     ep->config.winheight = win->Height;
  238.  
  239.     if(Ep->win->WScreen->Font != NULL)
  240.         Nw.Height = Ep->win->WScreen->Font->ta_YSize + 3;    /* height */
  241.     else
  242.         Nw.Height = GfxBase->DefaultFont->tf_YSize + 3;
  243.  
  244.     itxt.IText = ep->name;
  245.  
  246.     /* pretending spaces are always 8 */
  247.     Nw.Width  = 60 + IntuiTextLength(&itxt);          /* width */
  248.  
  249.     Nw.LeftEdge = ep->config.iwinx;
  250.     Nw.TopEdge  = ep->config.iwiny;
  251.  
  252.     if (Nw.LeftEdge + Nw.Width > win->WScreen->Width)   /* keep in bounds */
  253.         Nw.LeftEdge = win->WScreen->Width - Nw.Width;
  254.  
  255.     if (Nw.TopEdge + Nw.Height > win->WScreen->Height)
  256.         Nw.TopEdge = win->WScreen->Height - Nw.Height;
  257.  
  258.     Nw.Title = ep->wtitle;
  259.     Nw.Flags = ICONIFYFLAGS;
  260.  
  261.     if (!ep->modified)
  262.     {     /* no CLOSE */
  263.         Nw.Flags |= WFLG_CLOSEGADGET;
  264.     }
  265.  
  266.     Nw.DetailPen = TEXT_BPEN;
  267.     Nw.BlockPen  = TEXT_FPEN;
  268.  
  269. #ifdef NOTDEF
  270.     if (win->Flags & WFLG_WINDOWACTIVE)      /*  KTS */
  271.         Nw.Flags |= WFLG_ACTIVATE;
  272. #endif
  273.  
  274.     sprintf (ep->wtitle, "%s", ep->name);
  275.  
  276.     if (newwin = opensharedwindow (&Nw))
  277.     {
  278.         Nw.BlockPen  = (unsigned char)-1;
  279.  
  280.         rem_prop (ep);
  281.         closesharedwindow (win);
  282.  
  283.         ep->iconmode = 1;
  284.         ep->win     = newwin;
  285.     }
  286.     }
  287. } /* iconify */
  288.  
  289.  
  290. void uniconify (void)
  291. {
  292.     ED    * ep = Ep;
  293.     WIN * win = ep->win;
  294.     WIN * newwin;
  295.     RP    * rp;
  296.  
  297.     if (ep->iconmode)
  298.     {
  299.     ep->config.iwinx    = win->LeftEdge;
  300.     ep->config.iwiny    = win->TopEdge;
  301.     Nw.LeftEdge  = ep->config.winx;
  302.     Nw.TopEdge   = ep->config.winy;
  303.     Nw.Width     = ep->config.winwidth;
  304.     Nw.Height    = ep->config.winheight;
  305.     Nw.Title     = ep->wtitle;
  306.     Nw.Flags     = WINDOWFLAGS;
  307.     Nw.DetailPen = TEXT_BPEN;
  308.     Nw.BlockPen  = TEXT_FPEN;
  309.  
  310.     if (newwin = opensharedwindow (&Nw))
  311.     {
  312.         closesharedwindow (win);
  313.  
  314.         win = ep->win = newwin;
  315.         rp    = win->RPort;
  316.  
  317.         if (ep->font)
  318.         SetFont (rp, ep->font);
  319.  
  320.         set_window_params ();
  321.         rest_prop (ep);
  322.  
  323.         MShowTitle     = 0;
  324.         ep->iconmode = FALSE;
  325.  
  326.         text_adjust (TRUE);
  327.  
  328.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  329.         window_title ();
  330.     }
  331.     }
  332. } /* uniconify */
  333.  
  334.  
  335. void do_newwindow (void)
  336. {
  337.     WIN * win;
  338.  
  339.     if (Ep)
  340.     text_sync ();
  341.  
  342.     if (text_init (Ep, NULL, &Nw))
  343.     {
  344.     Nw.Title = Ep->wtitle;
  345.     Nw.Flags = WINDOWFLAGS;
  346.  
  347.     if (win = opensharedwindow (&Nw))
  348.     {
  349.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  350.  
  351.         Ep->win = win;
  352.         set_window_params ();
  353.         Ep->propgad = (struct Gadget *)add_prop (win);
  354.  
  355.         text_load ();
  356.     }
  357.     else
  358.     {
  359.         text_uninit ();
  360.     } /* if opensharedwindow */
  361.     } /* if text_init */
  362. } /* do_newwindow */
  363.  
  364.  
  365. /*
  366.  *  openwindow with geometry specification.  Negative number specify
  367.  *  relative-right / relative-left (leftedge & topedge), or relative-width /
  368.  *  relative height (width & height).
  369.  *
  370.  *    <leftedge><topedge><width><height>
  371.  *
  372.  *  Example:    +10+10-20-20    Open window centered on screen 10 pixels
  373.  *                from the border on all sides.
  374.  */
  375.  
  376. void do_openwindow (void)
  377. {
  378.     WIN *win;
  379.  
  380.     if (Ep)
  381.     text_sync ();
  382.  
  383.     if (text_init (Ep, NULL, &Nw))
  384.     {
  385.     GeometryToNW (av[1], &Nw);
  386.  
  387.     Nw.Title = Ep->wtitle;
  388.     Nw.Flags = WINDOWFLAGS;
  389.  
  390.     if (win = opensharedwindow (&Nw))
  391.     {
  392.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  393.  
  394.         Ep->win = win;
  395.         set_window_params ();
  396.         Ep->propgad = (struct Gadget *)add_prop (win);
  397.  
  398.         text_load ();
  399.     }
  400.     else
  401.     {
  402.         text_uninit ();
  403.     } /* if opensharedwindow */
  404.     } /* if text_init */
  405. } /* do_openwindow */
  406.  
  407.  
  408. WIN * TOpenWindow (struct NewWindow * nw)
  409. {
  410.     WIN * win;
  411.     struct Screen * PubScreen;
  412.  
  413.     /* get WB or any screen */
  414.     PubScreen = LockPubScreen (XDMEArgs.publicscreenname);
  415.  
  416.     if (PubScreen)
  417.     {
  418.     nw->MinWidth = PubScreen->WBorLeft + PubScreen->WBorRight +
  419.         4 * GfxBase->DefaultFont->tf_XSize;
  420.     nw->MinHeight = PubScreen->WBorTop + PubScreen->Font->ta_YSize * 5 +
  421.         1 + PubScreen->WBorBottom;
  422.     }
  423.     else
  424.     {
  425.     nw->MinWidth  = 100;
  426.     nw->MinHeight = 50;
  427.     }
  428.  
  429.     win = OpenWindowTags (nw,
  430.         WA_RptQueue, 1,
  431.         WA_PubScreen, PubScreen,
  432.         WA_AutoAdjust, TRUE,
  433.         TAG_DONE);
  434.  
  435.     if (PubScreen)
  436.     UnlockPubScreen (XDMEArgs.publicscreenname, PubScreen);
  437.  
  438.     return (win);
  439. } /* TOpenWindow */
  440.  
  441.  
  442. WIN * opensharedwindow (struct NewWindow *nw)
  443. {
  444.     WIN * win;
  445.  
  446.     if (Sharedport)
  447.     nw->IDCMPFlags = 0L;
  448.     else
  449.     nw->IDCMPFlags = IDCMPFLAGS;
  450.  
  451.     win = TOpenWindow (nw);
  452.  
  453.     if (win)
  454.     {
  455.     long xend = win->Width - win->BorderRight - 1;
  456.     long yend = win->Height- win->BorderBottom - 1;
  457.  
  458.     if (Sharedport)
  459.     {
  460.         win->UserPort = Sharedport;
  461.         ModifyIDCMP (win, IDCMPFLAGS);
  462.     } else
  463.     {
  464.         Sharedport = win->UserPort;
  465.     }
  466.  
  467.     if (xend > win->BorderLeft && yend > win->BorderTop)
  468.     {
  469.         SetAPen (win->RPort, nw->DetailPen);
  470.         RectFill (win->RPort, win->BorderLeft, win->BorderTop, xend, yend);
  471.         SetAPen (win->RPort, nw->BlockPen);
  472.     }
  473.     }
  474.  
  475.     return (win);
  476. } /* opensharedwindow */
  477.  
  478.  
  479. /* the following function straight from RKM by TJM */
  480.  
  481. static void StripIntuiMessages (struct MsgPort *mp, struct Window *win)
  482. {
  483.     IMESS *msg, *succ;
  484.  
  485.     msg = (IMESS *)mp->mp_MsgList.lh_Head;
  486.  
  487.     while (succ = (IMESS *)msg->ExecMessage.mn_Node.ln_Succ)
  488.     {
  489.     if (msg->IDCMPWindow == win)
  490.     {
  491.         Remove ((struct Node *)msg);
  492.         ReplyMsg ((struct Message *)msg);
  493.     }
  494.  
  495.     msg = succ;
  496.     }
  497. } /* StripIntuiMessages */
  498.  
  499.  
  500. /* modifed TJM to close win's immediately using CloseWindowSafely from RKM */
  501. void closesharedwindow (WIN * win)
  502. {
  503.     if (win)
  504.     {
  505.     SetWindowTitles (win, "", (char *)-1);
  506.     ClearMenuStrip (win);
  507.  
  508.     Forbid ();
  509.  
  510.     StripIntuiMessages (win->UserPort,win);
  511.  
  512.     win->UserPort = NULL;
  513.     ModifyIDCMP (win,0);
  514.  
  515.     Permit ();
  516.  
  517.     CloseWindow (win);
  518.     }
  519. } /* closesharedwindow */
  520.  
  521.  
  522. int getyn (char * title, char * text, char * gads, ...)
  523. {
  524.     va_list va;
  525.     int     result;
  526.     static struct EasyStruct es =
  527.     {
  528.     sizeof (struct EasyStruct),
  529.     0L, 0, 0, 0
  530.     };
  531.  
  532.     va_start (va, gads);
  533.  
  534.     es.es_Title        = title;
  535.     es.es_TextFormat   = text;
  536.     es.es_GadgetFormat = gads;
  537.  
  538.     result = EasyRequestArgs (Ep->win, &es, NULL, va);
  539.  
  540.     va_end (va);
  541.  
  542.     return (result);
  543. } /* getyn */
  544.  
  545.  
  546. Prototype void show_title (char *);
  547.  
  548. void show_title (char * title)
  549. {
  550.     if (globalflags.Showtitle != 0 && !Ep->iconmode)
  551.     {
  552.     SetWindowTitles (Ep->win, title, (char *)-1);
  553.     MShowTitle = 3;
  554.     } /* if showtitle */
  555. } /* show_title */
  556.  
  557.  
  558. void title (char * fmt, ...)
  559. {
  560.     va_list va;
  561.  
  562.     va_start (va, fmt);
  563.  
  564.     vsprintf (tmp_buffer, fmt, va);
  565.  
  566.     show_title (tmp_buffer);
  567. } /* title */
  568.  
  569.  
  570. void window_title (void)
  571. {
  572.     if (globalflags.memoryfail)
  573.     {
  574.     title(" -- NO MEMORY -- ");
  575.     globalflags.memoryfail = 0;
  576.     text_redisplay ();
  577.     }
  578.  
  579.     if (globalflags.MForceTitle)
  580.     {
  581.     MShowTitle = 0;
  582.     globalflags.MForceTitle = 0;
  583.     }
  584.  
  585.     if (Ep->iconmode)
  586.     return;
  587.  
  588.     if (MShowTitle)
  589.     {
  590.     MShowTitle --;
  591.     } else
  592.     {
  593.     int    len;
  594.     int    maxlen;
  595.     WORD   width;
  596.     FONT * oldfont;
  597.     ED   * ep    = Ep;
  598.     WIN  * win   = ep->win;
  599.     RP   * rp    = win->RPort;
  600.     UBYTE  c;
  601.     struct TextExtent bounds;
  602.  
  603.     len = text_colno ();
  604.     if (!(c = Current[len]) )
  605.         c = ' ';
  606.  
  607.     sprintf (ep->wtitle, "%4ld/%-4ld %3ld %02x %c %s %s",
  608.         text_lineno (),
  609.         text_lines (),
  610.         len+1,
  611.         c,
  612.         (ep->modified ? '*' : ' '),
  613.         text_name (),
  614.         (text_imode() ? "" : "Ovr")
  615.     );
  616.  
  617.     len = strlen (ep->wtitle);
  618.  
  619.     if (len < Columns && Columns < 128)
  620.     {
  621.         setmem (ep->wtitle+len, Columns - len + 1, ' ');
  622.         ep->wtitle[Columns + 1] = 0;
  623.     }
  624.  
  625.     /*
  626.      *  Update title
  627.      */
  628.  
  629.     oldfont = win->RPort->Font;
  630.     SetFont (rp, win->WScreen->RastPort.Font);
  631.  
  632.     win->Title = ep->wtitle;
  633.  
  634.     SetAPen (rp, TEXT_FPEN);
  635.     SetBPen (rp, TITLE_BPEN);
  636.     SetDrMd (rp, JAM2);
  637.     SetWrMsk (rp, 0xFF);
  638.  
  639.     width = win->Width - 96;
  640.  
  641.     maxlen = TextFit (rp, ep->wtitle, len, &bounds, NULL,
  642.             1L, width, rp->Font->tf_YSize);
  643.  
  644.     /* if (len < maxlen)
  645.         len = maxlen; dead assign */
  646.  
  647.     /* write new text */
  648.     SetWindowTitles(ep->win, ep->wtitle, (char *)-1); /* PATCH_NULL each time the window was deactivated, parts of the title went away */
  649.     Move (rp, 30, rp->Font->tf_Baseline+1);
  650.     Text (rp, ep->wtitle, maxlen);      /* No flash */
  651.  
  652.     /* clear to eol */
  653.     width = win->Width - 66;
  654.  
  655.     if (rp->cp_x < width) {
  656.  
  657. /* >>> PATCH_NULL 28-07-94 - Patch to clear the Title in a right manner */
  658. /* DQ(bug("Titeling %ld\n", (win->Flags & WFLG_WINDOWACTIVE)&&1)); */
  659.         if (win->Flags & WFLG_WINDOWACTIVE) {
  660.         SetAPen(rp, 3);
  661.         } else {
  662.         SetAPen(rp, 0);
  663.         }
  664.         RectFill (rp, rp->cp_x, 1, width, rp->Font->tf_YSize);
  665. /* <<< PATCH_NULL 28-07-94 - this patch works only w/ 4-color WB */
  666.  
  667. //          EraseRect (rp, rp->cp_x, 1, width, rp->Font->tf_YSize);
  668.     } /* if */
  669.  
  670.     SetAPen (rp, TEXT_FPEN);
  671.     SetBPen (rp, TEXT_BPEN);
  672.     SetFont (rp, oldfont);
  673.     }
  674. } /* window_title */
  675.  
  676.  
  677. void set_window_params (void)
  678. {
  679.     ED    * ep = Ep;
  680.     WIN * win = ep->win;
  681.     RP    * rp = win->RPort;
  682.     WORD  t;
  683.     WORD  x;
  684.  
  685.     /* Set Character-Size */
  686.     Xsize = rp->Font->tf_XSize;
  687.     Ysize = rp->Font->tf_YSize + LineDistance;
  688.  
  689.     /* Set Borders */
  690.     Xbase = win->BorderLeft;
  691.     Ybase = win->BorderTop;
  692.  
  693.     /* Find Width/Height */
  694.     Xpixs   = win->Width - win->BorderRight - Xbase;
  695.     Ypixs   = win->Height- win->BorderBottom- Ybase;
  696.  
  697.     /* Find Width/Height in Characters */
  698.     Columns = Xpixs / Xsize;
  699.     Lines    = Ypixs / Ysize;
  700.  
  701.     /* Now Calculate Xpixs/Ypixs */
  702.     Xpixs = Xbase + Columns * Xsize - 1;
  703.     Ypixs = Ybase + Lines    * Ysize - 1;
  704.  
  705.     /* Set Base for Text() */
  706.     XTbase  =  Xbase;
  707.     YTbase  =  Ybase + rp->Font->tf_Baseline + (LineDistance + 1)/2;
  708.  
  709.     /* Set Pens */
  710.     SetAPen(rp, TEXT_FPEN);
  711.     SetBPen(rp, TEXT_BPEN);
  712.  
  713.     /* Initialize Arrays of X/Y-Coords for faster rendering */
  714.     for (t=0, x=0; t<MAXLINELEN; t++, x += Xsize)
  715.     ColumnPos[t] = x;
  716.  
  717.     for (t=0, x=0; t<MAXROWS; t++, x += Ysize)
  718.     RowPos[t] = x;
  719. } /* set_window_params */
  720.  
  721.  
  722. /* resize cols rows */
  723.  
  724. void do_resize (void)
  725. {
  726.     WIN * win     = Ep->win;
  727.     int   cols     = atoi (av[1]);
  728.     int   rows     = atoi (av[2]);
  729.     WORD  width  = (cols * Xsize) + win->BorderLeft +
  730.            win->BorderRight;
  731.     WORD  height = (rows * Ysize) + win->BorderTop +
  732.            win->BorderBottom;
  733.  
  734.     if (cols < 2 || rows < 1)
  735.     {
  736.     error ("resize:\nCannot make window this small.\n"
  737.            "Window must have at least 2 columns and 1 row !");
  738.     } else if (width > win->WScreen->Width - win->LeftEdge ||
  739.         height > win->WScreen->Height - win->TopEdge)
  740.         {
  741.     error ("resize:\nwindow too big (move it to\n"
  742.            "upper left corner and retry)");
  743.     } else
  744.     {
  745.     SizeWindow (win, width - win->Width, height - win->Height);
  746.     Delay (5);    /* wait 0.1 seconds for OS to resize */
  747.     }
  748. } /* do_resize */
  749.  
  750.  
  751. /* Convert geometry to nw params. */
  752.  
  753. char * geoskip (char * ptr, int * pval, int * psgn)
  754. {
  755.     ptr = skip_whitespace (ptr);
  756.  
  757.     if (*ptr == '-')
  758.     *psgn = -1;
  759.     else
  760.     *psgn = 1;
  761.  
  762.     if (*ptr == '-' || *ptr == '+')
  763.     ptr ++;
  764.  
  765.     *pval = strtol (ptr, &ptr, 0);
  766.  
  767.     return (ptr);
  768. } /* geoskip */
  769.  
  770.  
  771. /* Convert GEO-String to NewWindow-structure */
  772.  
  773. void GeometryToNW (char * geo, struct NewWindow *nw)
  774. {
  775.     int       n;
  776.     int       sign;
  777.     struct Screen scr;
  778.  
  779.     GetScreenData (&scr, sizeof (scr), WBENCHSCREEN, NULL);
  780.  
  781.     if (*geo)
  782.     {
  783.     geo = geoskip (geo, &n, &sign);
  784.     if (sign > 0)
  785.         nw->LeftEdge = n;
  786.     else
  787.         nw->LeftEdge = scr.Width - n;
  788.     }
  789.  
  790.     if (*geo)
  791.     {
  792.     geo = geoskip (geo, &n, &sign);
  793.     if (sign > 0)
  794.         nw->TopEdge = n;
  795.     else
  796.         nw->TopEdge = scr.Height - n;
  797.     }
  798.  
  799.     if (*geo)
  800.     {
  801.     geo = geoskip (geo, &n, &sign);
  802.     if (sign > 0)
  803.         nw->Width = n;
  804.     else
  805.         nw->Width = scr.Width - nw->LeftEdge - n;
  806.     }
  807.  
  808.     if (*geo)
  809.     {
  810.     /* geo = dead assign */ geoskip (geo, &n, &sign);
  811.     if (sign > 0)
  812.         nw->Height = n;
  813.     else
  814.         nw->Height = scr.Height - nw->TopEdge - n;
  815.     }
  816. } /* GeometryToNW */
  817.  
  818.  
  819. /* prop gadget stuff (TJM) */
  820.  
  821. void rest_prop (ED * ep)
  822. {
  823.     if (ep->propgad)
  824.     {
  825.     struct PropGadget * pg = (struct PropGadget *)ep->propgad;
  826.  
  827.     AddGList (ep->win, &pg->scroller, 0, NUM_GADS, NULL);
  828.     RefreshGList (&pg->scroller, ep->win, NULL, NUM_GADS);
  829.     }
  830. } /* rest_prop */
  831.  
  832.  
  833. void rem_prop (ED * ep)
  834. {
  835.     if (ep->propgad)
  836.     {
  837.     struct PropGadget * pg = (struct PropGadget *)ep->propgad;
  838.  
  839.     RemoveGList (ep->win, &pg->scroller, NUM_GADS);
  840.     }
  841. } /* rest_prop */
  842.  
  843.  
  844. struct PropGadget * add_prop (struct Window * win)
  845. {
  846.     struct PropGadget * pg;
  847.     struct DrawInfo   * mydrawinfo;
  848.     struct Image      * dummy;
  849.     struct TagItem    taglist[5] =
  850.     {
  851.     SYSIA_Which, NULL,
  852.     SYSIA_DrawInfo, NULL,
  853.     SYSIA_Size, 0,
  854.     };
  855.     UWORD  height, size,
  856.        size_width, size_height,
  857.        depth_width, depth_height;
  858.  
  859.     /* Get memory */
  860.     if (!(pg = AllocMem (sizeof(struct PropGadget), 0)))
  861.     return NULL;
  862.  
  863.     /* copy default flags/modes/etc. */
  864.     movmem (&gadgetdefaults, pg, sizeof(struct PropGadget));
  865.  
  866.     /* find out sizes */
  867.     mydrawinfo = GetScreenDrawInfo (win->WScreen);
  868.  
  869.     if (win->WScreen->ViewPort.Modes & HIRES)
  870.     {
  871.     size = SYSISIZE_MEDRES;
  872.  
  873.     /* Don't use HIRES, since that will produce too large images */
  874.     /* if (win->WScreen->ViewPort.Modes & LACE)
  875.         size = SYSISIZE_HIRES;
  876.     else */
  877.     }
  878.     else
  879.     size = SYSISIZE_LOWRES;
  880.  
  881.     taglist[0].ti_Data = DEPTHIMAGE;
  882.     taglist[1].ti_Data = (ULONG)mydrawinfo;
  883.     taglist[2].ti_Data = size;
  884.     taglist[3].ti_Tag  = IA_Height;    /* the depth-gadget needs a height */
  885.     taglist[3].ti_Data = win->BorderTop;
  886.     taglist[4].ti_Tag  = TAG_END;
  887.  
  888.     /* get size of depth-gadget */
  889.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  890.     {
  891. oom:
  892.     FreeMem (pg, sizeof (struct PropGadget));
  893.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  894.     return (NULL);
  895.     }
  896.  
  897.     depth_width  = dummy->Width;
  898.     depth_height = dummy->Height;
  899.  
  900. #ifdef NOT_DEF
  901.     pg->depth.GadgetRender = pg->depth.SelectRender = (APTR)pg->depthimage;
  902. #else
  903.     DisposeObject (dummy);
  904. #endif
  905.  
  906.     /* Get the ZOOMIMAGE here because we need the height */
  907.     taglist[0].ti_Data = ZOOMIMAGE;
  908.  
  909.     if (!(pg->iconifyimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  910.     goto oom;
  911.  
  912.     pg->iconify.GadgetRender = pg->iconify.SelectRender = (APTR)pg->iconifyimage;
  913.  
  914.     taglist[0].ti_Data = SIZEIMAGE;
  915.     taglist[3].ti_Tag  = TAG_END;
  916.  
  917.     /* get size of size-gadget */
  918.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  919.     {
  920.     DisposeObject (pg->iconifyimage);
  921.     goto oom;
  922.     }
  923.  
  924.     size_width    = dummy->Width;     /* width of up/down-gadgets */
  925.     size_height = dummy->Height;    /* bottom offset */
  926.  
  927.     /* we don't need the image anymore */
  928.     DisposeObject (dummy);
  929.  
  930.     taglist[0].ti_Data = UPIMAGE;
  931.  
  932.     if (!(pg->upimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  933.     {
  934.     DisposeObject (pg->iconifyimage);
  935.     goto oom;
  936.     }
  937.  
  938.     pg->up.GadgetRender = pg->up.SelectRender = (APTR)pg->upimage;
  939.  
  940.     height = pg->upimage->Height;
  941.  
  942.     taglist[0].ti_Data = DOWNIMAGE;
  943.  
  944.     if (!(pg->downimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  945.     {
  946.     DisposeObject (pg->iconifyimage);
  947.     DisposeObject (pg->upimage);
  948.     goto oom;
  949.     }
  950.  
  951.     pg->down.GadgetRender = pg->down.SelectRender = (APTR)pg->downimage;
  952.  
  953.     /* Release drawinfo */
  954.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  955.  
  956.     /* Now init all sizes/positions */
  957.     pg->scroller.TopEdge    = depth_height + 1;
  958.     pg->scroller.Height     = -(depth_height + size_height + 2*height + 2);
  959.     pg->up.LeftEdge =
  960.     pg->down.LeftEdge   = -(size_width - 1);
  961.     pg->scroller.LeftEdge   = -(size_width - 4);
  962.     pg->down.TopEdge        = -(size_height + height - 1);
  963.     pg->up.TopEdge        = pg->down.TopEdge - height;
  964.     pg->up.Width =
  965.     pg->down.Width        = size_width;
  966.     pg->scroller.Width        = size_width - 6;
  967.     pg->up.Height =
  968.     pg->down.Height     = height;
  969. #ifdef NOT_DEF
  970.     pg->depth.Width        = pg->depthimage->Width;
  971.     pg->depth.Height        = pg->depthimage->Height;
  972.     pg->depth.LeftEdge        = -(pg->depth.Width - 1);
  973. #endif
  974.     pg->iconify.Width        = pg->iconifyimage->Width;
  975.     pg->iconify.Height        = pg->iconifyimage->Height;
  976.     pg->iconify.LeftEdge    = -(depth_width + pg->iconify.Width - 2);
  977.  
  978.     /* Other fields */
  979.     pg->scroller.GadgetRender = (APTR)&pg->simage;
  980.     pg->scroller.SpecialInfo  = (APTR)&pg->pinfo;
  981.  
  982.     /* Link gadgets */
  983.     pg->scroller.NextGadget = &pg->up;
  984.     pg->up.NextGadget        = &pg->down;
  985.     pg->down.NextGadget     = &pg->iconify;
  986.     /* pg->depth.NextGadget    = &pg->iconify; */
  987.  
  988.     /* and add them to the window */
  989.     AddGList (win, &pg->scroller, 0, NUM_GADS, NULL);
  990.     RefreshGList (&pg->scroller, win, NULL, NUM_GADS);
  991.  
  992.     noadj = 0;        /* allow scroller refreshing */
  993.  
  994.     /* return field */
  995.     return (pg);
  996. } /* add_prop */
  997.  
  998.  
  999. void free_prop (struct PropGadget * pg)
  1000. {
  1001.     if (pg)
  1002.     {
  1003.     /* Free elements */
  1004.     DisposeObject (pg->upimage);
  1005.     DisposeObject (pg->downimage);
  1006.     /* DisposeObject (pg->depthimage); */
  1007.     DisposeObject (pg->iconifyimage);
  1008.  
  1009.     /* Free struct */
  1010.     FreeMem (pg, sizeof (struct PropGadget));
  1011.     }
  1012. } /* free_prop */
  1013.  
  1014.  
  1015. void prop_adj (void)
  1016. {
  1017.     ULONG VertBody, VertPot;
  1018.  
  1019.      /* block adjustment when already set by prop gad */
  1020.     if (!Ep->propgad || noadj || Ep->iconmode)
  1021.     return;
  1022.  
  1023.     /* If there are less lines than the window has, the scroller has
  1024.        full size */
  1025.     if (Ep->lines <= Lines)
  1026.     {
  1027.     VertPot  = 0;
  1028.     VertBody = MAXBODY;
  1029.     } else
  1030.     {
  1031.     ULONG overlap = Lines - (Lines * PageJump) / 100;
  1032.     ULONG total;
  1033.  
  1034.     /* If we have more lines visible than the text actually has (ie.
  1035.        there are empty lines visible) the total number of lines is
  1036.        (topline + Lines) and the position is at its maximum. Else, the
  1037.        number of lines is the length of the text and the position is
  1038.        (toppos / invisible lines) */
  1039.  
  1040.     if (Ep->topline + Lines > Ep->lines)
  1041.     {
  1042.         total = Ep->topline + Lines;
  1043.  
  1044.         VertPot  = MAXPOT;
  1045.     } else
  1046.     {
  1047.         total = Ep->lines;
  1048.  
  1049.         VertPot  = (Ep->topline * MAXPOT) / (total - Lines);
  1050.     }
  1051.  
  1052.     /* The body-size is (number of lines for jump-scroll / all other
  1053.        lines */
  1054.     VertBody = ((Lines - overlap) * MAXBODY) / (total - overlap);
  1055.     }
  1056.  
  1057.     /* set it */
  1058.     NewModifyProp (Ep->propgad, Ep->win, NULL,
  1059.     ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1060.     MAXPOT, VertPot,
  1061.     MAXBODY, VertBody,
  1062.     1
  1063.     );
  1064. } /* prop_adj */
  1065.  
  1066.  
  1067. ULONG new_top (void)
  1068. {
  1069.     ULONG top;
  1070.  
  1071.     if (Ep->lines <= Lines)
  1072.     {
  1073.     top = 0;
  1074.     } else
  1075.     {
  1076.     ULONG total;
  1077.  
  1078.     if (Ep->topline + Lines > Ep->lines)
  1079.         total = Ep->topline;
  1080.     else
  1081.         total = Ep->lines - Lines;
  1082.  
  1083.     top = ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot *
  1084.         total / MAXPOT;
  1085.  
  1086.     /* we may have to adjust the body-size (the user already adjust the
  1087.        position) */
  1088.     if (Ep->topline + Lines > Ep->lines)
  1089.     {
  1090.         ULONG VertBody;
  1091.         ULONG overlap = Lines - (Lines * PageJump) / 100;
  1092.  
  1093.         VertBody = ((Lines - overlap) * MAXBODY) /
  1094.                (Ep->topline + Lines - overlap);
  1095.  
  1096.         NewModifyProp (Ep->propgad, Ep->win, NULL,
  1097.         ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1098.         MAXPOT, ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot,
  1099.         MAXBODY, VertBody,
  1100.         1
  1101.         );
  1102.     }
  1103.     }
  1104.  
  1105.     return (top);
  1106. } /* new_top */
  1107.  
  1108.  
  1109. void do_title (void)
  1110. {
  1111.     static char buffer[256];
  1112.  
  1113.     strncpy ((char *)buffer, (char *)av[1], 255);
  1114.     buffer[255] = 0;
  1115.  
  1116.     show_title ((char *)buffer);
  1117. } /* do_title */
  1118.  
  1119.  
  1120. void do_showlog (void)
  1121. {
  1122.     ED * ep = Ep;
  1123.     int t;
  1124.     UBYTE * ptr;
  1125.  
  1126.     /* Neues Fenster auf */
  1127.     do_newwindow ();
  1128.  
  1129.     /* Nur wenn das ging ... */
  1130.     if (ep != Ep)
  1131.     {
  1132.     for (t=0; t<numlogs; t++)
  1133.     {
  1134.         if (!(ptr = allocline (strlen (log_messages[t]))) )
  1135.         break;
  1136.  
  1137.         strcpy (ptr, log_messages[t]);
  1138.  
  1139.         SETLINE(Ep,t,ptr);
  1140.     }
  1141.  
  1142.     text_redisplay ();
  1143.     }
  1144. } /* do_showlog */
  1145.  
  1146.  
  1147. static void log (char * text)
  1148. {
  1149.     /* Wenn schon alle Slots voll sind, Platz schaffen */
  1150.     if (numlogs == MAX_LOG)
  1151.     {
  1152.     /* Erste message freigeben */
  1153.     free (log_messages[0]);
  1154.  
  1155.     /* Rest nach vorne schieben */
  1156.     movmem (&log_messages[1], &log_messages[0],
  1157.                         sizeof(char *) * (MAX_LOG - 1));
  1158.  
  1159.     /* Anzahl anpassen */
  1160.     numlogs --;
  1161.     }
  1162.  
  1163.     /* Wenn neuer log angefügt werden konnte, anzahl erhöhen */
  1164.     if (log_messages[numlogs] = strdup (text))
  1165.     numlogs ++;
  1166. } /* log */
  1167.  
  1168.  
  1169. void error (char * fmt, ...)
  1170. {
  1171.     va_list va;
  1172.     static struct EasyStruct es =
  1173.     {
  1174.     sizeof (struct EasyStruct),
  1175.     NULL,
  1176.     "XDME Error",
  1177.     NULL,
  1178.     "Ok"
  1179.     };
  1180.  
  1181.     va_start (va, fmt);
  1182.  
  1183.     globalflags.Abortcommand = 1;
  1184.  
  1185.     if (globalflags.NoRequest)
  1186.     {
  1187.     char * ptr;                /* PATCH_NULL [25 Jan 1993] : line added */
  1188.  
  1189.     vsprintf (tmp_buffer, fmt, va);     /* PATCH_NULL [25 Jan 1993] : line added */
  1190.     ptr = tmp_buffer;            /* PATCH_NULL [25 Jan 1993] : line added */
  1191.  
  1192.     while (*ptr) {                      /* PATCH_NULL [25 Jan 1993] : line added */
  1193.         if (*ptr == '\n') *ptr = ' ';   /* PATCH_NULL [25 Jan 1993] : line added */
  1194.         ptr ++;                /* PATCH_NULL [25 Jan 1993] : line added */
  1195.     } /* while */                /* PATCH_NULL [25 Jan 1993] : line added */
  1196.  
  1197.     show_title (tmp_buffer);            /* PATCH_NULL [25 Jan 1993] : line added */
  1198.     log (tmp_buffer);
  1199.     }
  1200.     else
  1201.     {
  1202.     es.es_TextFormat = fmt;
  1203.  
  1204.     EasyRequestArgs ((Ep ? Ep->win : NULL), &es, NULL, va);
  1205.  
  1206.     } /* if (not) noRequest */              /* PATCH_NULL [25 Jan 1993] : line added */
  1207.  
  1208.     va_end (va);
  1209. } /* error */
  1210.  
  1211.  
  1212. void warn (char * fmt, ...)
  1213. {
  1214.     va_list va;
  1215.  
  1216.     va_start (va, fmt);
  1217.  
  1218.     vsprintf (tmp_buffer, fmt, va);
  1219.  
  1220.     show_title (tmp_buffer);
  1221.     log (tmp_buffer);
  1222.  
  1223.     va_end (va);
  1224. } /* warn */
  1225.  
  1226.  
  1227. /*
  1228.     Changes the window-size and position. If the position is negative,
  1229.     it's calculated as offset from the right/bottom border. If
  1230.     width/height are negative, they are relative to the screen's
  1231.     width/height. If they are 0, they are not changed.
  1232. */
  1233.  
  1234. void do_setgeometry (void)      /* av[1..4]: X Y Width Height */
  1235. {
  1236.     static const char error_text[] =
  1237.     ":\n"
  1238.     "Cannot set window to\n";
  1239.     WORD top, left, width, height;
  1240.     SCREEN * screen;
  1241.     char * error_ptr = NULL;
  1242.     long   minsize = 0;
  1243.  
  1244.     left   = strtol (av[1], NULL, 0);
  1245.     top    = strtol (av[2], NULL, 0);
  1246.     width  = strtol (av[3], NULL, 0);
  1247.     height = strtol (av[4], NULL, 0);
  1248.  
  1249.     screen = Ep->win->WScreen;
  1250.  
  1251.     if (left < 0)
  1252.     left += screen->Width;
  1253.     if (top < 0)
  1254.     top += screen->Height;
  1255.     if (width < 0)
  1256.     width += screen->Width + 1;
  1257.     if (height < 0)
  1258.     height += screen->Height + 1;
  1259.  
  1260.     if (!width || Ep->iconmode)
  1261.     width = Ep->win->Width;
  1262.     if (!height || Ep->iconmode)
  1263.     height = Ep->win->Height;
  1264.  
  1265.     /* if the left/top is not ok, or we are not in iconmode AND the
  1266.        width/height is wrong ... */
  1267.     if (left < 0)
  1268.     error_ptr = "left edge negative";
  1269.     else if (top < 0)
  1270.     error_ptr = "top edge negative";
  1271.     else if (left > screen->Width)
  1272.     error_ptr = "left edge too big";
  1273.     else if (top > screen->Height)
  1274.     error_ptr = "top edge too big";
  1275.     else if (!Ep->iconmode)
  1276.     {
  1277.     if (width < Nw.MinWidth)
  1278.     {
  1279.         error_ptr = "width is too narrow\n(The minimal width is ";
  1280.         minsize = Nw.MinWidth;
  1281.     } else if (height < Nw.MinHeight)
  1282.     {
  1283.         error_ptr = "height is too low\n(The minimal height is ";
  1284.         minsize = Nw.MinHeight;
  1285.     } else if (left + width > screen->Width)
  1286.         error_ptr = "right edge is too big";
  1287.     else if (top + height > screen->Height)
  1288.         error_ptr = "bottom edge is too big";
  1289.     }
  1290.  
  1291.     if (error_ptr)
  1292.     {
  1293.     if (minsize != 0)
  1294.     {
  1295.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s%ld).",
  1296.             av[0], error_text, left, top, width, height, error_ptr,
  1297.             minsize);
  1298.     } else
  1299.     {
  1300.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s.",
  1301.             error_text, av[0], left, top, width, height, error_ptr);
  1302.     }
  1303.     } else
  1304.     {
  1305.     ChangeWindowBox (Ep->win, left, top, width, height);
  1306.     Delay (5);
  1307.     }
  1308. } /* do_setgeometry */
  1309.  
  1310.  
  1311. void do_toback (void)
  1312. {
  1313.     WindowToBack (Ep->win);
  1314. }
  1315.  
  1316.  
  1317. void do_tofront (void)
  1318. {
  1319.     WindowToFront (Ep->win);
  1320. }
  1321.  
  1322.  
  1323. /******************************************************************************
  1324. *****  ENDE win.c
  1325. ******************************************************************************/
  1326.